/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "AppService.h"
#include "PluginNasTypes.h"
#include "ApplicationServiceDataType.h"
#include "PluginConstants.h"
#include "JsonTransUtil.h"
#include "SmbContextWrapper.h"
#include "ProtectPluginFactory.h"
#include "ErrorCode.h"
#include <iostream>

#include "gtest/gtest.h"
#include "mockcpp/mockcpp.hpp"

using namespace Module;
using namespace PluginUtils;
using namespace AppProtect;

class AppServiceTest : public testing::Test {
public:
    void SetUp();
    void TearDown();
    static void SetUpTestCase();
    static void TearDownTestCase();
    // Stub stub;
    // std::shared_ptr<ScanQueue> m_ins;
};

void AppServiceTest::SetUp()
{
    // std::shared_ptr<BufferQueue<DirStat>> input = std::make_shared<BufferQueue<DirStat>>(10);
    // string scanOutputDirectory;
    // m_ins = make_shared<ScanQueue>(input, scanOutputDirectory);
}

void AppServiceTest::TearDown()
{
    GlobalMockObject::verify(); // 校验mock规范并清除mock规范
}

void AppServiceTest::SetUpTestCase()
{}

void AppServiceTest::TearDownTestCase()
{}

static int MountNas_Stub_SUC(void *ob, PluginUtils::NasMountParams& param, std::string &outSelectedSvcIp)
{
    std::cout << "MountNas_Stub_SUC get called" << std::endl;
    return Module::SUCCESS;
}

/*
 * 用例名称：DiscoverApplications
 * 前置条件：无
 * check点：发现应用
 **/
TEST_F(AppServiceTest, DiscoverApplications)
{
    std::vector<Application> returnValue;
    std::string appType;
    AppServiceExport::DiscoverApplications(returnValue, appType);         
}

/*
 * 用例名称：CheckApplication
 * 前置条件：无
 * check点：检查应用
 **/
TEST_F(AppServiceTest, CheckApplication)
{ 
    MOCKER_CPP(&Module::JsonHelper::JsonStringToStruct<NasShareExtendInfo>) // mockcpp 模板函数打桩
            .stubs()
            .will(returnValue(false))
            .then(returnValue(true));
    // MOCKER_CPP(&Module::JsonHelper::JsonStringToStruct<NasShareExtendInfo>) // mockcpp 模板函数打桩 内联函数无法打桩
    //         .stubs()
    //         .will(invoke(Stub_JsonStringToStruct_False))
    //         .then(invoke(Stub_JsonStringToStruct_True));
    ActionResult returnValue;
    ApplicationEnvironment appEnv;
    Application application;
    EXPECT_NO_THROW(AppServiceExport::CheckApplication(returnValue, appEnv, application)); 
    EXPECT_NO_THROW(AppServiceExport::CheckApplication(returnValue, appEnv, application));       
}

/*
 * 用例名称：getAuthTypeAndInitTGT
 * 前置条件：无
 * check点：获取类型和初始化TGT
 **/
TEST_F(AppServiceTest, getAuthTypeAndInitTGT)
{ 
    MOCKER_CPP(&Module::JsonHelper::JsonStringToStruct<NasShareExtendInfo>) // mockcpp 模板函数打桩
            .stubs()
            .will(returnValue(false))
            .then(returnValue(true));
    Application application;  
    std::string cifsAuthType;
    EXPECT_EQ(AppServiceExport::getAuthTypeAndInitTGT(application, cifsAuthType), false);
    application.auth.authType = AuthType::type::KERBEROS; 
    EXPECT_EQ(AppServiceExport::getAuthTypeAndInitTGT(application, cifsAuthType), false);
    application.auth.authType = AuthType::type::APP_PASSWORD;
    EXPECT_EQ(AppServiceExport::getAuthTypeAndInitTGT(application, cifsAuthType), true);        
}

/*
 * 用例名称：ListApplicationResourceV2
 * 前置条件：无
 * check点：列出应用资源
 **/
TEST_F(AppServiceTest, ListApplicationResourceV2)
{ 
    MOCKER_CPP(&Module::JsonHelper::JsonStringToStruct<NasShareExtendInfo>) // mockcpp 模板函数打桩
            .stubs()
            .will(returnValue(false))
            .then(returnValue(true));
    MOCKER_CPP(&AppServiceExport::ConstructResourceParam)
            .stubs()
            .will(returnValue(false))
            .then(returnValue(true));
    ResourceResultByPage returnValue;
    ListResourceRequest request;
    EXPECT_NO_THROW(AppServiceExport::ListApplicationResourceV2(returnValue, request));
    Application application; 
    request.applications.push_back(application);
    EXPECT_NO_THROW(AppServiceExport::ListApplicationResourceV2(returnValue, request));
    EXPECT_THROW(AppServiceExport::ListApplicationResourceV2(returnValue, request), AppProtectPluginException);        
}

/*
 * 用例名称：CheckSmbConnection
 * 前置条件：无
 * check点：检查smb连接情况
 **/
TEST_F(AppServiceTest, CheckSmbConnection)
{ 
    CifsConnectParams params;
    params.nasServerIpList.push_back("aaa");
    params.nasServerIpList.push_back("bbb");
    EXPECT_NO_THROW(AppServiceExport::CheckSmbConnection(params)); 
    params.authType = "krb5";
    EXPECT_NO_THROW(AppServiceExport::CheckSmbConnection(params));
    params.authType = "ntlmssp"; 
    EXPECT_NO_THROW(AppServiceExport::CheckSmbConnection(params));          
}

/*
 * 用例名称：TransformParm
 * 前置条件：无
 * check点：转换参数
 **/
TEST_F(AppServiceTest, TransformParm)
{ 
    ListResourceParam returnResourceParam;
    ListApplicationShareInfo shareInfo;
    Application application;
    ApplicationEnvironment appEnv;
    EXPECT_NO_THROW(AppServiceExport::TransformParm(returnResourceParam, shareInfo, application, appEnv));
    shareInfo.shareInfoReq.targetType = "HETEROGENEOUS"; 
    EXPECT_NO_THROW(AppServiceExport::TransformParm(returnResourceParam, shareInfo, application, appEnv));
    shareInfo.shareInfoReq.targetType = "HOMOGENEOUS";  
    EXPECT_NO_THROW(AppServiceExport::TransformParm(returnResourceParam, shareInfo, application, appEnv)); 
    shareInfo.shareInfoReq.cifsAuth.mode = KRB5AUTHMODE;
    EXPECT_NO_THROW(AppServiceExport::TransformParm(returnResourceParam, shareInfo, application, appEnv));
}

/*
 * 用例名称：ConstructResourceParam
 * 前置条件：无
 * check点：构建参数
 **/
TEST_F(AppServiceTest, ConstructResourceParam)
{ 
    // ListResourceRequest request;
    ListResourceParam listResourceParam;
    ListResourceRequest request;
    Application application;
    application.subType = "Fileset";
    application.name = "netapp_mdd_cifs";
    application.id = "a6014064-9fec-3dea-bade-de98a3336f13";
    application.extendInfo =  "{\"protocol\":\"Linux\",\"filters\":\"\",\"ip\":\"8.40.145.46\""
                                " ,\"fileType\":\"native\", \"domainName\":\"keber.host.com\",\"encryption\": \"0\""
                                        ",\"kerberosId\":\"0\",\"shareMode\":\"0\",\"directory\":\"/home\"}";
    application.auth.authType = AuthType::type::APP_PASSWORD;
    application.auth.authkey = "test_admin";
    application.auth.authPwd = "Huawei@123";
    application.auth.extendInfo =  "{\"krb5Conf\":\"krb5ConfValue\",\"password\":\"123456\""
                                ",\"keytab\":\"keytab_value\", \"configMode\":\"0\",\"shareMode\":\"0\"}";
    request.applications.push_back(application);
    request.condition.pageNo = 0;
    request.condition.pageSize = 1;
    EXPECT_NO_THROW(AppServiceExport::ConstructResourceParam(request, listResourceParam));
}